/* 
 * Copyright 2014 Josef Hertl.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package caetus.modelChecking.goal;

import caetus.modelChecking.role.ModelActor;
import caetus.modelChecking.variable.ModelBaseVariable;
import caetus.modelChecking.variable.ModelVariable;
import caetus.modelChecking.variable.ModelVariableType;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * This is a global map that holds secrecy goals for all the variables that are
 * required to be kept secret. It can only hold one secret per variable (map
 * implementation), but that is sufficient.
 *
 * @author Josef Hertl
 */
public class ModelGoalMap {

    private static Map<ModelBaseVariable, ModelGoalSecret> secretMap = new HashMap<ModelBaseVariable, ModelGoalSecret>();
    /**
     * The list of actors that can know the secret variable.
     */
    private static List<ModelActor> actorList;

    /**
     * Sets the list of actors that can by default share the secret variables.
     * Usually it is the list of all tokens.
     */
    public static void setActorList(List<ModelActor> actorList) {
        ModelGoalMap.actorList = actorList;
    }

    /**
     * Adds the given variable to as a secret goal. It is automatically kept
     * secret between all the tokens.
     *
     * @param variable The added variable.
     */
    public static void addVariableToSecretGoals(ModelBaseVariable variable) {
        secretMap.put(variable, new ModelGoalSecret(variable, "sec_" + variable.getVariableName().toLowerCase(), actorList));
    }

    /**
     *
     * @param variable The variable for which this method should find a secret.
     * @return Secret goal including the given variable, if such one exists.
     * Null otherwise.
     */
    public static ModelGoalSecret findSecretOfVariable(ModelBaseVariable variable) {
        return secretMap.get(variable);
    }

    /**
     * Used for the environment role and for goal declaration.
     *
     * @return List of all goal protocol ids.
     */
    public static List<ModelVariable> getProtocolIDs() {
        List<ModelVariable> resultList = new LinkedList<ModelVariable>();
        for (ModelBaseVariable baseVariable : secretMap.keySet()) {
            resultList.add(new ModelBaseVariable(secretMap.get(baseVariable).getSecretConstant(), ModelVariableType.PROTOCOL_ID));
        }
        return resultList;
    }

    /**
     * Used in Environment to determine items the intruder does NOT know.
     * @return List of all the variables that are secret - usually symmetric and
     * private keys.
     */
    public static List<ModelVariable> getAllSecretVariables() {
        List<ModelVariable> resultList = new LinkedList<ModelVariable>();
        for (ModelBaseVariable baseVariable : secretMap.keySet()) {
            resultList.add(secretMap.get(baseVariable).getVariableKeptSecret());
        }
        return resultList;
    }
}
